<template>
  <div class="input-select-multi" ref="root" @click="focusInput">
    <div class="tags" ref="tagsContainer">
      <el-tag
        v-for="(val, idx) in selected"
        :key="val"
        closable
        @close="removeAt(idx)"
        size="small"
        class="tag-item"
      >
        {{ getLabel(val) }}
      </el-tag>
      <el-input
        v-model="query"
        ref="inputRef"
        :placeholder="placeholder"
        size="small"
        class="inner-input"
        @focus="onFocus"
        @blur="onBlur"
        @input="onInput"
        @keydown.native="onKeydown"
        clearable
      />
    </div>

    <Transition name="fade">
      <ul v-if="open && filtered.length" class="dropdown-list" @mousedown.prevent>
        <li
          v-for="(opt, idx) in filtered"
          :key="opt.value"
          :class="{ 'is-active': idx === highlightIndex, 'is-selected': isSelected(opt.value) }"
          @mousedown.prevent="toggleOption(opt)"
        >
          {{ opt.label }}
          <span class="checkmark" v-if="isSelected(opt.value)">✔</span>
        </li>
      </ul>
    </Transition>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted, onBeforeUnmount, Transition } from 'vue'
import { ElInput, ElTag } from 'element-plus'

// 显式声明局部组件
const components = {
  ElInput,
  ElTag,
  Transition
}

const props = defineProps({
  modelValue: { type: Array, default: () => [] },
  options: { type: Array, default: () => [] },
  placeholder: { type: String, default: '请输入或选择' },
})
const emit = defineEmits(['update:modelValue'])

const root = ref(null)
const inputRef = ref(null)
const query = ref('')
const open = ref(false)
const highlightIndex = ref(0)

const selected = ref([])

const normalizedOptions = computed(() =>
  props.options.map(o =>
    typeof o === 'string' ? { label: o, value: o } : o
  )
)

watch(
  () => props.modelValue,
  (val) => {
    if (!Array.isArray(val)) return
    selected.value = val.filter(v => normalizedOptions.value.some(opt => opt.value === v))
    query.value = ''
  },
  { immediate: true }
)

const filtered = computed(() => {
  const q = query.value.trim().toLowerCase()
  return normalizedOptions.value.filter(opt =>
    opt.label.toLowerCase().includes(q)
  )
})

function isSelected(val) {
  return selected.value.includes(val)
}

function toggleOption(opt) {
  const index = selected.value.indexOf(opt.value)
  if (index === -1) {
    selected.value.push(opt.value)
  } else {
    selected.value.splice(index, 1)
  }
  emit('update:modelValue', [...selected.value])
  query.value = ''
  open.value = false
}

function removeAt(idx) {
  selected.value.splice(idx, 1)
  emit('update:modelValue', [...selected.value])
}

function getLabel(val) {
  const found = normalizedOptions.value.find(opt => opt.value === val)
  return found ? found.label : val
}

watch(filtered, (newFiltered) => {
  open.value = newFiltered.length > 0
  if (highlightIndex.value >= newFiltered.length) {
    highlightIndex.value = 0
  }
})

watch(query, () => {
  open.value = filtered.value.length > 0
})

function onFocus() {
  open.value = filtered.value.length > 0
  highlightIndex.value = 0
}

function onBlur() {
  setTimeout(() => {
    open.value = false
  }, 150)
}

function onInput() {
  // open 状态由 watcher 控制
}

function onKeydown(e) {
  if (e.key === 'ArrowDown') {
    highlightIndex.value = Math.min(highlightIndex.value + 1, filtered.value.length - 1)
    e.preventDefault()
  } else if (e.key === 'ArrowUp') {
    highlightIndex.value = Math.max(highlightIndex.value - 1, 0)
    e.preventDefault()
  } else if (e.key === 'Enter') {
    if (filtered.value.length && highlightIndex.value >= 0) {
      toggleOption(filtered.value[highlightIndex.value])
      e.preventDefault()
    }
    if(!query.value && selected.value.length) {
      selected
      
    }
  } else if (e.key === 'Backspace' && !query.value && selected.value.length) {
    selected.value.pop()
    emit('update:modelValue', [...selected.value])
  } else if (e.key === 'Escape') {
    open.value = false
  }
}

function focusInput() {
  inputRef.value?.focus?.()
}

function onClickOutside(e) {
  if (!root.value?.contains(e.target)) {
    open.value = false
  }
}

onMounted(() => {
  document.addEventListener('click', onClickOutside)
})
onBeforeUnmount(() => {
  document.removeEventListener('click', onClickOutside)
})
</script>

<style scoped lang="scss">
.input-select-multi {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 4px 8px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  position: relative;
  background: #fff;
  cursor: text;
  min-height: 38px;
  box-sizing: border-box;
  width: 100%;
  max-width: 600px;
}

.tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
}

.tag-item {
  user-select: none;
}

.inner-input{
  flex: 1 1 150px;
  min-width: 100px;
  border: none !important;
  box-shadow: none !important;
  outline: none !important;
  background: transparent;
  padding: 0 !important;
  margin: 0 !important;
  font-size: 14px;
  :deep(.el-input__wrapper) {
    border: 0 ;
    box-shadow: unset ;
  }
}

.inner-input input {
  border: none !important;
  box-shadow: none !important;
  outline: none !important;
  background: transparent;
  font-size: 14px;
  padding: 4px 0;
}

.dropdown-list {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  max-height: 250px;
  overflow-y: auto;
  background: #fff;
  border: 1px solid #ebeef5;
  box-shadow: 0 6px 16px rgba(0,0,0,0.08);
  border-radius: 4px;
  z-index: 1000;
  padding: 6px 0;
  margin: 0;
  list-style: none;
}
.dropdown-list li {
  padding: 8px 36px 8px 12px;
  cursor: pointer;
  white-space: nowrap;
  position: relative;
  display: flex;
  align-items: center;
}
.dropdown-list li.is-active {
  background: #f5f7fa;
}
.dropdown-list li.is-selected {
  background-color: var(--el-fill-color-light);
  color: var(--el-color-primary);
    font-weight: 700;
}
.checkmark {
  position: absolute;
  right: 12px;
  color: white;
  font-weight: bold;
  user-select: none;
}
.fade-enter-active,
.fade-leave-active {
  transition: all 0.15s ease;
}
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
  transform: translateY(-4px);
}
</style>
